package cn.cpf.app.gobang.frame;

import cn.cpf.app.gobang.ctrl.AppContext;
import cn.cpf.app.gobang.ctrl.Application;
import cn.cpf.app.gobang.global.Config;
import cn.cpf.app.gobang.global.Global;
import cn.cpf.app.gobang.global.GobangDefined;
import cn.cpf.app.gobang.impl.LambdaMouseListener;
import cn.cpf.app.gobang.modal.Place;
import cn.cpf.app.gobang.modal.PlayerType;
import com.github.cosycode.common.ext.hub.Throws;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;

/**
 * <b>Description : </b> 棋盘面板
 * <p>
 * <b>created in </b> 2017/12/11
 *
 * @author CPF
 * @since 1.0
 **/
public class GoBangPanel extends JPanel implements LambdaMouseListener {

    private JTextArea jTextArea = null;

    /**
     * Create the panel.
     */
    public GoBangPanel() {
        setLayout(null);
        addMouseListener(this);
        setBackground(SystemColor.inactiveCaption);
        init();
    }

    public void init() {
        removeAll();
        repaint();
        Global.init();
        init2();
        run();
    }

    private void init2() {
        jTextArea = new JTextArea();
        jTextArea.setBounds(510, 20, 500, 480);
        jTextArea.setBackground(Color.gray);
        jTextArea.setVisible(true);
        add(jTextArea);
    }

    public void showScore() {
        jTextArea.setText(Global.getSituation().toString());
    }


    /**
     * 运行
     */
    protected void run() {
        new Thread(() -> {
            while (Global.isComRunnable()) {
                Throws.con(100, Thread::sleep).logThrowable();
                try {
                    // 若当前执棋手是 COM
                    if (PlayerType.COM.equals(Global.getSituation().getCurRole())) {
                        // TODO 显示轮到COM来继续的信息
                        // 获取COM计算的位置
                        Place computedPalce = AppContext.getEvaluatedPlace();
                        if (computedPalce == null) {
                            isAnotherGame("已经没有可以下的位子,是否开启下一局", "阿拉拉");
                        }
                        // 落子
                        boolean isWin = Application.context().pushPiece(computedPalce);
                        // 判断是否结束
                        if (isWin) {
                            Global.setComRunnable(false);
                            isAnotherGame("congratulation", "再来一局");
                        }
                    } else {
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    // 暂停COM
                    Global.setComRunnable(false);
                    JOptionPane.showMessageDialog(null, e.getMessage(), e.toString(), JOptionPane.ERROR_MESSAGE);
                    break;
                }
            }
        }).start();
    }

    /**
     * 是否再来一局
     */
    public void isAnotherGame(String title, String message) {
        int checkResult = JOptionPane.showConfirmDialog(this, "再来一局", "congratulation", JOptionPane.YES_NO_OPTION);
        if (checkResult == JOptionPane.YES_OPTION) {
            init();
        }
    }


    @Override
    public void mouseReleased(MouseEvent e) {
        switch (Config.mouseClickState) {
            case PLAY -> {
                if (e.getSource() instanceof GoBangPanel) {// 如果点击的是空白
                    if (PlayerType.MAN.equals(Global.getSituation().getCurRole())) {// 若论到人下棋
                        // 获取落子点
                        Point point = e.getPoint();
                        Place place = GobangDefined.convertLocationToPlace(point);
                        // 如果点击的落子点位置没有棋子
                        if (Global.getSituation().getPiece(place) == null) {
                            // 添加棋子
                            boolean isWin = Application.context().pushPiece(place);
                            // 判断是否结束
                            if (isWin) {
                                Global.setComRunnable(false);
                                isAnotherGame("congratulation", "再来一局");
                            } else {
                                run();
                            }
                        }
                        // 判断是否胜利
                    }
                }
            }
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.black);
        final int halfXY = Config.PIECE_WIDTH / 2;
        final int maxXY = Config.BOARD_LENGTH * Config.PIECE_WIDTH - halfXY;
        for (int i = maxXY; i > 0; i -= Config.PIECE_WIDTH) {
            g.drawLine(halfXY, i, maxXY, i);
            g.drawLine(i, halfXY, i, maxXY);
        }
    }

}
